Repository navigation
fix(protocols): makers name the rejected argument and value in error messages - #2405
Conversation
|
Supersedes #2404 for #2296 — same scope, but that PR's cross-review found a wrong-requirement message, under-tested guards, and an overclaim about coverage (see the comment there). This one pins every site individually and stays within the issue's own checklist. Thanks to @Qiu-LingYan for the first pass at this — if the fixes above land there instead, I'll close this one. |
…messages
Several _make_* builders rejected a bad caller-supplied argument with the
reader's parse-error text ("invalid format"), which gives no indication of
which argument was wrong or what value triggered it. #2296.
- sctp.py: all 11 identical `len(flags) != 1` guards across the chunk
makers, plus _make_chunk_data's empty-data guard, _make_param_hostname's
NUL-termination guard, and _make_cause_invalid_stream's reserved-length
guard.
- mh.py: make()'s unsupported-data-type guard, _make_opt_bad/_make_opt_auth's
length guards, _make_opt_badf's empty-data guard, and _make_opt_pad's
Pad1-length warning. Added the missing Raises:/Warns: docstring sections.
- tcp.py: _make_mptcp_capable now names which optional field was given
without its predecessor.
- hip.py: _make_locator's fallback branch (the one site #2276 missed).
- pcapng.py: _make_block_dsb's fallback branch (the one site #2273 missed).
_make_chunk_data's flags= example in the issue doesn't match any real
parameter on that method (it takes reserved/I/U/B/E, not flags), so its
exact wording was applied to the 11 makers that do take flags, and
_make_chunk_data got a data-shaped message instead.
Test: tests/protocols/test_maker_invalid_format_messages_2296_unit.py (new,
22 tests/82 subtests, one class per site group); confirmed 66 failed/20
passed against unpatched pcapkit, each failure a message-text mismatch.
tests/protocols/ in full: 2011 passed/51370 subtests/0 failed. mypy and
pylint findings on the 5 touched files are unchanged from main.
Four other maker-side sites still use the generic text but aren't in
#2296's checklist -- HOPOPT._make_opt_pad, IPv6_Opts._make_opt_pad,
HTTP.make, PCAPNG.make -- tracked separately rather than folded in here.
e11cdb9 to
d0fd8cd
Compare
|
Review: GOOD TO GO at |
|
Coverage: 91.72% (unit tier, Python 3.15,
Per-file detail: the |
Follow-up to #2405, which left these out of #2296's checklist. #2406. - hopopt.py / ipv6_opts.py: _make_opt_pad's Pad1-length warning, matching MH._make_opt_pad's text from #2405 (alias swapped). - httpv2.py: HTTP.make's unsupported-frame-type guard. - pcapng.py: PCAPNG.make's unsupported-block-type guard (the dispatcher, not _make_block_dsb, which #2405 already fixed). Added the missing Raises: docstring section on the two make() guards, matching #2405's MH.make/_make_block_dsb docstrings. Test: tests/protocols/test_maker_invalid_format_messages_2406_unit.py (new, 9 tests/18 subtests), plus a ReadersKeepInvalidFormat pin that _read_opt_pad on both protocols still says "invalid format" -- the exact twin of the maker guard changed here. Confirmed fail-without-fix: 12 failures against unpatched pcapkit, each a message-text mismatch. tests/protocols/ in full: 2020 passed/51388 subtests/0 failed. mypy and pylint findings on the 4 touched files are unchanged from main.
…egistry and registration prose (#1103) #1103 whole-repo prose sweep over the maker-message wave (#2296, #2404, #2405, #2407) and the __proto_dest__ registry refactor (#2392, #2403). Docstrings corrected where the prose did not match the code: * ``Protocol`` -> ``ProtocolBase`` in the ``register``/``register_protocol`` cross-references (protocol.py, internet.py, link.py, transport.py, sctp.py, registry/protocols.py). * ``Raises:`` entries for the ``bool`` port guard (#2287) in TCP, UDP and SCTP ``make``, and for HTTP/1's request-without-``uri`` guard. * ``protochain`` documented on both sides of its narrowing to ``None`` (protocol.py, misc/null.py, #2317), and ``__init__`` names the ``__own_make_keywords__`` exception to its keyword check. * IP reassembly names the IPv6 ``M`` bit and which buffer an atomic fragment is isolated from (#2270); ``_check_code`` names ``register_protocol_code`` among its callers (#2186). * HIP's shared lifetime helper says where the octet appears instead of counting the makers that carry it, and ``_make_opt_pad`` warns and makes a ``PadN`` rather than raising as its reader does. Before/after narration replaced with present tense, the pattern #1103's round 6 banned: the ``__proto_dest__`` prose in the registration and vendor tests, and the #2296 maker-message module docstring. AST guard (``ast.dump`` via util/vendor_code_changed.py's ``code_of``, with docstrings and bare string literals stripped) confirms all 16 touched files are prose-only against e48062c. 135 tests and 334 subtests pass across the four touched test modules, tests/test_docstring_contract.py, and the convention and issue/PR-role guards in tests/project/.
…egistry and registration prose (#1103) #1103 whole-repo prose sweep over the maker-message wave (#2296, #2404, #2405, #2407) and the __proto_dest__ registry refactor (#2392, #2403). Docstrings corrected where the prose did not match the code: * ``Protocol`` -> ``ProtocolBase`` in the ``register``/``register_protocol`` cross-references (protocol.py, internet.py, link.py, transport.py, sctp.py, registry/protocols.py). * ``Raises:`` entries for the ``bool`` port guard (#2287) in TCP, UDP and SCTP ``make``, and for HTTP/1's request-without-``uri`` guard. * ``protochain`` documented on both sides of its narrowing to ``None`` (protocol.py, misc/null.py, #2317), and ``__init__`` names the ``__own_make_keywords__`` exception to its keyword check. * IP reassembly names the IPv6 ``M`` bit and which buffer an atomic fragment is isolated from (#2270); ``_check_code`` names ``register_protocol_code`` among its callers (#2186). * HIP's shared lifetime helper says where the octet appears instead of counting the makers that carry it, and ``_make_opt_pad`` warns and makes a ``PadN`` rather than raising as its reader does. Before/after narration replaced with present tense, the pattern #1103's round 6 banned: the ``__proto_dest__`` prose in the registration and vendor tests, the ``register_protocol_code`` key-check narration, and the #2296 and #2406 maker-message module docstrings. AST guard (``ast.dump`` via util/vendor_code_changed.py's ``code_of``, with docstrings and bare string literals stripped) confirms all 16 touched files are prose-only against e48062c. 130 tests and 334 subtests pass across the four touched test modules, tests/test_docstring_contract.py, and tests/project/test_conventions_doc_claims.py, tests/project/test_docs_issue_pr_roles_1103_unit.py and tests/project/test_issue_refs_in_comments.py.
…egistry and registration prose (#1103) #1103 whole-repo prose sweep over the maker-message wave (#2296, #2404, #2405, #2407) and the __proto_dest__ registry refactor (#2392, #2403). Docstrings corrected where the prose did not match the code: * ``Protocol`` -> ``ProtocolBase`` in the ``register``/``register_protocol`` cross-references (protocol.py, internet.py, link.py, transport.py, sctp.py, registry/protocols.py). * ``Raises:`` entries for the ``bool`` port guard (#2287) in TCP, UDP and SCTP ``make``, and for HTTP/1's request-without-``uri`` guard. * ``protochain`` documented on both sides of its narrowing to ``None`` (protocol.py, misc/null.py, #2317), and ``__init__`` names the ``__own_make_keywords__`` exception to its keyword check. * IP reassembly names the IPv6 ``M`` bit and which buffer an atomic fragment is isolated from (#2270); ``_check_code`` names ``register_protocol_code`` among its callers (#2186). * HIP's shared lifetime helper says where the octet appears instead of counting the makers that carry it, and ``_make_opt_pad`` warns and makes a ``PadN`` rather than raising as its reader does. Before/after narration replaced with present tense, the pattern #1103's round 6 banned: * the ``__proto_dest__`` prose in the registration and vendor tests, and the ``register_protocol_code`` key-check narration; * the #2296 and #2406 maker-message module docstrings -- readers are exempt by design rather than "deliberately untouched", and the HTTP ``frame=None`` case is outside the guard rather than one the guard "has not widened to"; * the ``_NameLease`` rationale and the ``register_protocol`` name-collision note in registry/protocols.py, which described a fix and a redesign in the past tense; * TCP's ``_make_mptcp_unknown`` length comment, which contrasted the current expression with "the former" one. AST guard (``ast.dump`` via util/vendor_code_changed.py's ``code_of``, with docstrings and bare string literals stripped) confirms all 16 touched files are prose-only against e48062c. 129 tests pass (1 pre-existing skip) with 334 subtests across the four touched test modules, tests/test_docstring_contract.py, tests/project/test_conventions_doc_claims.py, tests/project/test_docs_issue_pr_roles_1103_unit.py and tests/project/test_issue_refs_in_comments.py.
Problem: of the 60 pull requests merged in the #2312-#2407 range, only #2334, #2336, #2337, #2340 and #2348 wrote a 1.5.0 changelog entry, and #2398 and #2403 only reworded lines that were already there. Every other user-visible change in the range -- wire-semantics fixes, maker guards, reassembly behaviour, public-API and error-message changes -- went unrecorded, so the entry no longer describes the release. Fix: one entry per user-visible pull request, in each module section's existing style and ordered by the issue it closes. Two pairs share a bullet, since each is the direct follow-up of the other: #2393 with #2401, and #2405 with #2407. The diff on the entry file is purely additive. Internal-only work is left out deliberately: dependency and action bumps (#2387 to #2391), test-only and docs-prose passes (#2333, #2376, #2379, #2380, #2402), the unreachable-branch removal (#2378), and the #: comment marker the HIP Group and Packet crawlers now write (#2381). That last one renders nothing either way: the marker lands inside the generated _missing_ body, conf.py's exclude-members drops _missing_ from autodoc, and a comment in a method body is not an attribute comment to begin with. #2392 and #2403 are recorded together, under Added rather than Fixed, for the declarations they introduce: __proto_key__ on the seven classes owning a __proto__ registry (#2392), __proto_dest__ on the four enum registries and Vendor.PROTO_DEST to generate it (#2403). Both PRs added the autodoc entries, so both are rendered public attributes. #2392's rejection-message change is deliberately not recorded as a fix: the bare "code must be ..." text it prefixed came from _check_code, which #2193 introduced and which is in no release tag -- absent at v1.5.0b14 -- so no released version ever emitted it. #2403 is no longer skipped as internal because it reworded an existing bullet to name __proto_dest__ while nothing credited the attribute's introduction. Four claims are corrected against the source rather than carried over: FTP_DATA shipped in pcapkit/protocols/application/ftp.py from 1.0.0, not 1.4.0 (class FTP_DATA(Raw) is there at v1.0.0); #2365's pre-fix fallback read cmmd.value, so a .value-carrying object was accepted unchecked rather than raising; #2399 left the dpkt adapter and the adapters' ModuleNotFound raises alone, so it claims no universal prefix; and #2397's old tail did name the version it got, so the entry quotes it and gains the :issue:`2302` it was missing. #2370's "a Section Header Block ... still fails" sentence is dropped: #2369 settles the byte order first, and an SHB built from raw octets with ctx=None now rebuilds byte-exact in both byte orders. CHANGELOG.md is regenerated with util/changelog_md.py. Test: tests/project/ in full, 0 failures, including test_changelog_md.py's in-step and supported-subset checks; util/changelog_md.py --check reports the two files in step; the entry parses under docutils with no structural warning.
…egistry and registration prose (#1103) #1103 whole-repo prose sweep over the maker-message wave (#2296, #2404, #2405, #2407) and the __proto_dest__ registry refactor (#2392, #2403). Docstrings corrected where the prose did not match the code: * ``Protocol`` -> ``ProtocolBase`` in the ``register``/``register_protocol`` cross-references (protocol.py, internet.py, link.py, transport.py, sctp.py, registry/protocols.py). * ``Raises:`` entries for the ``bool`` port guard (#2287) in TCP, UDP and SCTP ``make``, and for HTTP/1's request-without-``uri`` guard. * ``protochain`` documented on both sides of its narrowing to ``None`` (protocol.py, misc/null.py, #2317), and ``__init__`` names the ``__own_make_keywords__`` exception to its keyword check. * IP reassembly names the IPv6 ``M`` bit and which buffer an atomic fragment is isolated from (#2270); ``_check_code`` names ``register_protocol_code`` among its callers (#2186). * HIP's shared lifetime helper says where the octet appears instead of counting the makers that carry it, and ``_make_opt_pad`` warns and makes a ``PadN`` rather than raising as its reader does. Before/after narration replaced with present tense, the pattern #1103's round 6 banned: * the ``__proto_dest__`` prose in the registration and vendor tests, and the ``register_protocol_code`` key-check narration; * the #2296 and #2406 maker-message module docstrings -- readers are exempt by design rather than "deliberately untouched", and the HTTP ``frame=None`` case is outside the guard rather than one the guard "has not widened to"; * the ``_NameLease`` rationale and the ``register_protocol`` name-collision note in registry/protocols.py, which described a fix and a redesign in the past tense; * TCP's ``_make_mptcp_unknown`` length comment, which contrasted the current expression with "the former" one. AST guard (``ast.dump`` via util/vendor_code_changed.py's ``code_of``, with docstrings and bare string literals stripped) confirms all 16 touched files are prose-only against e48062c. 129 tests pass (1 pre-existing skip) with 334 subtests across the four touched test modules, tests/test_docstring_contract.py, tests/project/test_conventions_doc_claims.py, tests/project/test_docs_issue_pr_roles_1103_unit.py and tests/project/test_issue_refs_in_comments.py.
Problem: of the 60 pull requests merged in the #2312-#2407 range, only #2334, #2336, #2337, #2340 and #2348 wrote a 1.5.0 changelog entry, and #2398 and #2403 only reworded lines that were already there. Every other user-visible change in the range -- wire-semantics fixes, maker guards, reassembly behaviour, public-API and error-message changes -- went unrecorded, so the entry no longer describes the release. Fix: one entry per user-visible pull request, in each module section's existing style and ordered by the issue it closes. Three pairs share a bullet, since each is the direct follow-up or counterpart of the other: #2393 with #2401, #2405 with #2407, and #2392 with #2403. The diff on the entry file is purely additive. Internal-only work is left out deliberately: dependency and action bumps (#2387 to #2391), test-only and docs-prose passes (#2333, #2376, #2379, #2380, #2402), the unreachable-branch removal (#2378), and the #: comment marker the HIP Group and Packet crawlers now write (#2381). That last one renders nothing either way: the marker lands inside the generated _missing_ body, conf.py's exclude-members drops _missing_ from autodoc, and a comment in a method body is not an attribute comment to begin with. #2392 and #2403 are recorded together, under Added rather than Fixed, for the declarations they introduce: __proto_key__ on each class owning a __proto__ registry (#2392), __proto_dest__ on the enum registries and Vendor.PROTO_DEST to generate it (#2403). The bullet names those classes and registries rather than counting them, per the no-counted-numbers rule for the unreleased entry. Both PRs added the autodoc entries, so both are rendered public attributes. #2392's rejection-message change is deliberately not recorded as a fix: the bare "code must be ..." text it prefixed came from _check_code, which #2193 introduced and which is in no release tag -- absent at v1.5.0b14 -- so no released version ever emitted it. #2403 is no longer skipped as internal because it reworded an existing bullet to name __proto_dest__ while nothing credited the attribute's introduction. Four claims are corrected against the source rather than carried over: FTP_DATA shipped in pcapkit/protocols/application/ftp.py from 1.0.0, not 1.4.0 (class FTP_DATA(Raw) is there at v1.0.0); #2365's pre-fix fallback read cmmd.value, so a .value-carrying object was accepted unchecked rather than raising; #2399 left the dpkt adapter and the adapters' ModuleNotFound raises alone, so it claims no universal prefix; and #2397's old tail did name the version it got, so the entry quotes it and gains the :issue:`2302` it was missing. #2370's "a Section Header Block ... still fails" sentence is dropped: #2369 settles the byte order first, and an SHB built from raw octets with ctx=None now rebuilds byte-exact in both byte orders. CHANGELOG.md is regenerated with util/changelog_md.py. Test: tests/project/ in full, 0 failures, including test_changelog_md.py's in-step and supported-subset checks; util/changelog_md.py --check reports the two files in step; the entry parses under docutils with no structural warning.
#1103 whole-repo prose sweep over the maker-message wave (#2296, #2404, #2405, #2407) and the __proto_dest__ registry refactor (#2392, #2403). Docstrings corrected where the prose did not match the code: * ``Protocol`` -> ``ProtocolBase`` in the ``register``/``register_protocol`` cross-references (protocol.py, internet.py, link.py, transport.py, sctp.py, registry/protocols.py). * ``Raises:`` entries for the ``bool`` port guard (#2287) in TCP, UDP and SCTP ``make``, and for HTTP/1's request-without-``uri`` guard. * ``protochain`` documented on both sides of its narrowing to ``None`` (protocol.py, misc/null.py, #2317), and ``__init__`` names the ``__own_make_keywords__`` exception to its keyword check. * IP reassembly names the IPv6 ``M`` bit and which buffer an atomic fragment is isolated from (#2270); ``_check_code`` names ``register_protocol_code`` among its callers (#2186). * HIP's shared lifetime helper says where the octet appears instead of counting the makers that carry it, and ``_make_opt_pad`` warns and makes a ``PadN`` rather than raising as its reader does. Before/after narration replaced with present tense, the pattern #1103's round 6 banned: * the ``__proto_dest__`` prose in the registration and vendor tests, and the ``register_protocol_code`` key-check narration; * the #2296 and #2406 maker-message module docstrings -- readers are exempt by design rather than "deliberately untouched", and the HTTP ``frame=None`` case is outside the guard rather than one the guard "has not widened to"; * the ``_NameLease`` rationale and the ``register_protocol`` name-collision note in registry/protocols.py, which described a fix and a redesign in the past tense; * TCP's ``_make_mptcp_unknown`` length comment, which contrasted the current expression with "the former" one. AST guard (``ast.dump`` via util/vendor_code_changed.py's ``code_of``, with docstrings and bare string literals stripped) confirms all 16 touched files are prose-only against e48062c. 129 tests pass (1 pre-existing skip) with 334 subtests across the four touched test modules, tests/test_docstring_contract.py, tests/project/test_conventions_doc_claims.py, tests/project/test_docs_issue_pr_roles_1103_unit.py and tests/project/test_issue_refs_in_comments.py.
Problem: of the 60 pull requests merged in the #2312-#2407 range, only #2334, #2336, #2337, #2340 and #2348 wrote a 1.5.0 changelog entry, and #2398 and #2403 only reworded lines that were already there. Every other user-visible change in the range -- wire-semantics fixes, maker guards, reassembly behaviour, public-API and error-message changes -- went unrecorded, so the entry no longer describes the release. Fix: one entry per user-visible pull request, in each module section's existing style and ordered by the issue it closes. Three pairs share a bullet, since each is the direct follow-up or counterpart of the other: #2393 with #2401, #2405 with #2407, and #2392 with #2403. The diff on the entry file is purely additive. Internal-only work is left out deliberately: dependency and action bumps (#2387 to #2391), test-only and docs-prose passes (#2333, #2376, #2379, #2380, #2402), the unreachable-branch removal (#2378), and the #: comment marker the HIP Group and Packet crawlers now write (#2381). That last one renders nothing either way: the marker lands inside the generated _missing_ body, conf.py's exclude-members drops _missing_ from autodoc, and a comment in a method body is not an attribute comment to begin with. #2392 and #2403 are recorded together, under Added rather than Fixed, for the declarations they introduce: __proto_key__ on each class owning a __proto__ registry (#2392), __proto_dest__ on the enum registries and Vendor.PROTO_DEST to generate it (#2403). The bullet names those classes and registries rather than counting them, per the no-counted-numbers rule for the unreleased entry. Both PRs added the autodoc entries, so both are rendered public attributes. #2392's rejection-message change is deliberately not recorded as a fix: the bare "code must be ..." text it prefixed came from _check_code, which #2193 introduced and which is in no release tag -- absent at v1.5.0b14 -- so no released version ever emitted it. #2403 is no longer skipped as internal because it reworded an existing bullet to name __proto_dest__ while nothing credited the attribute's introduction. Four claims are corrected against the source rather than carried over: FTP_DATA shipped in pcapkit/protocols/application/ftp.py from 1.0.0, not 1.4.0 (class FTP_DATA(Raw) is there at v1.0.0); #2365's pre-fix fallback read cmmd.value, so a .value-carrying object was accepted unchecked rather than raising; #2399 left the dpkt adapter and the adapters' ModuleNotFound raises alone, so it claims no universal prefix; and #2397's old tail did name the version it got, so the entry quotes it and gains the :issue:`2302` it was missing. #2370's "a Section Header Block ... still fails" sentence is dropped: #2369 settles the byte order first, and an SHB built from raw octets with ctx=None now rebuilds byte-exact in both byte orders. CHANGELOG.md is regenerated with util/changelog_md.py. Test: tests/project/ in full, 0 failures, including test_changelog_md.py's in-step and supported-subset checks; util/changelog_md.py --check reports the two files in step; the entry parses under docutils with no structural warning.
make testpasses, and a test case covers the changeWhat is the purpose of your pull request?
fix — bug fixDescription
Fixes #2296.
_make_*builders that reject a bad caller-supplied argument reported the reader's parse-error text (invalid format), giving no indication of which argument was wrong or what value triggered it.Covers every site named in the issue: all 11 identical
flagsguards plus_make_chunk_data/_make_param_hostname/_make_cause_invalid_streaminsctp.py;make/_make_opt_bad/_make_opt_auth/_make_opt_badf/_make_opt_padinmh.py(also added the missingRaises:/Warns:docstring sections);_make_mptcp_capableintcp.py; and the one surviving generic-message branch each inhip.py's_make_locatorandpcapng.py's_make_block_dsb(the branches #2276/#2273 didn't touch).Note:
#2296's own repro calls_make_chunk_data(Chunk(0), flags=b'\x00\x00'), but that method has noflagsparameter (it takesreserved/I/U/B/E) — the issue's exact wording was applied to the 11 makers that actually takeflags, and_make_chunk_datagot adata-shaped message instead.Four other maker-side sites keep the generic text but weren't in #2296's checklist —
HOPOPT._make_opt_pad,IPv6_Opts._make_opt_pad,HTTP.make,PCAPNG.make(the dispatcher, not_make_block_dsb) — tracked as a follow-up in #2406 rather than folded in here.Test:
tests/protocols/test_maker_invalid_format_messages_2296_unit.py(new, 22 tests/82 subtests, one class per site group, each pinning the full message text plus the maker's valid-input case; independently confirmed each of the 22 changed sites is caught individually by reverting it alone). Confirmed fail-without-fix: 66 failed/20 passed against unpatchedpcapkit.tests/protocols/in full: 0 failures, same skip baseline asmain. mypy and pylint findings on the 5 touched files are unchanged frommain.